﻿using DTcms.Core.Common.Emum;
using DTcms.Core.Common.Extensions;
using DTcms.Core.Common.Helper;
using DTcms.Core.DBFactory.Database;
using DTcms.Core.IServices;
using DTcms.Core.Model.Models;
using DTcms.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace DTcms.Core.Services
{
    /// <summary>
    /// 会员金额日志接口实现
    /// </summary>
    public class MemberAmountLogService : BaseService, IMemberAmountLogService
    {
        private readonly IMemberGroupService _memberGroupService;

        public MemberAmountLogService(IDbContextFactory contentFactory,
            IMemberGroupService memberGroupService) : base(contentFactory)
        {
            _memberGroupService = memberGroupService;
        }

        /// <summary>
        /// 根据条件获取一条记录
        /// </summary>
        public async Task<MemberAmountLogDto> QueryAsync(Expression<Func<MemberAmountLogDto, bool>> funcWhere,
            WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //联合查询重新组合
            var result = from a in _context.Set<MemberAmountLog>()
                         from u in _context.Set<ApplicationUser>().Where(u => u.Id == a.UserId)
                         select (new MemberAmountLogDto
                         {
                             Id = a.Id,
                             UserId = a.UserId,
                             UserName = u.UserName,
                             Value = a.Value,
                             Remark = a.Remark,
                             AddTime = a.AddTime
                         });
            //加入查询条件并返回一条
            return await result.FirstOrDefaultAsync(funcWhere);
        }

        /// <summary>
        /// 根据条件获取列表
        /// </summary>
        public async Task<IEnumerable<MemberAmountLogDto>> QueryListAsync(int top, Expression<Func<MemberAmountLogDto, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //联合查询重新组合
            var result = from a in _context.Set<MemberAmountLog>()
                         from u in _context.Set<ApplicationUser>().Where(u => u.Id == a.UserId)
                         select (new MemberAmountLogDto
                         {
                             Id = a.Id,
                             UserId = a.UserId,
                             UserName = u.UserName,
                             Value = a.Value,
                             Remark = a.Remark,
                             AddTime = a.AddTime
                         });
            result = result.Where(funcWhere);//加入查询条件
            result = LinqExtensions.OrderByBatch(result, orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 根据条件获取分页列表
        /// </summary>
        public async Task<PaginationList<MemberAmountLogDto>> QueryPageAsync(int pageSize, int pageIndex,
            Expression<Func<MemberAmountLogDto, bool>> funcWhere, string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //联合查询重新组合
            var result = from a in _context.Set<MemberAmountLog>()
                         from u in _context.Set<ApplicationUser>().Where(u => u.Id == a.UserId)
                         select (new MemberAmountLogDto
                         {
                             Id = a.Id,
                             UserId = a.UserId,
                             UserName = u.UserName,
                             Value = a.Value,
                             Remark = a.Remark,
                             AddTime = a.AddTime
                         });
            result = result.Where(funcWhere);//加入查询条件
            result = LinqExtensions.OrderByBatch<MemberAmountLogDto>(result, orderBy);//调用Linq扩展类排序
            return await PaginationList<MemberAmountLogDto>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 新增余额记录，须同时增加会员余额，检查升级
        /// </summary>
        public async Task<MemberAmountLog> AddAsync(MemberAmountLog model, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var userModel = await _context.Set<Members>().FirstOrDefaultAsync(x => x.UserId == model.UserId);
            if (userModel == null)
            {
                throw new ResponseException("会员账户不存在或已删除");
            }
            //如果是负数，检查会员余额是否够扣减
            if (model.Value < 0 && userModel.Amount < (model.Value * -1))
            {
                throw new ResponseException("会员账户余额不足本次扣减");
            }
            userModel.Amount += model.Value;//添减余额
            //如果是正数则检查是否需要升级
            if (model.Value > 0)
            {
                //查询当前会员组
                var currGroupModel = await _memberGroupService.QueryAsync(x => x.Id == userModel.GroupId);
                if (currGroupModel == null)
                {
                    throw new ResponseException("会员组不存在或已删除", ErrorCode.NotFound, StatusCodes.Status404NotFound);
                }
                //检查有无可升级的会员组
                var upgradeGroupModel = await _memberGroupService.QueryAsync(x =>
                x.Id != currGroupModel.Id && x.IsUpgrade == 1 && x.Amount <= model.Value, "-Amount");
                if (upgradeGroupModel != null && upgradeGroupModel.Amount >= currGroupModel.Amount)
                {
                    userModel.GroupId = upgradeGroupModel.Id;
                }
            }
            //新增余额记录，更新用户余额
            await _context.Set<MemberAmountLog>().AddAsync(model);
            await this.SaveAsync();

            return model;
        }
    }
}
